﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using SarkothFarmer.Helpers;
using Zeta;
using Zeta.Common;
using Zeta.CommonBot;
using Zeta.CommonBot.Settings;
using Zeta.Internals.Actors;

namespace SarkothFarmer.ClassSpecifics
{
    internal class Common
    {
        private DiaItem itemToLoot;
        private static List<DiaItem> blacklist = new List<DiaItem>();
        public static List<DiaItem> Blacklist
        {
            get { return blacklist; }
        }
        private Stopwatch blacklistTimer = new Stopwatch();
        private Stopwatch TPTimer = new Stopwatch();

        public virtual void MoveTo(Vector3 v)
        {
            ZetaDia.Me.UsePower(SNOPower.Walk, v, ZetaDia.Me.WorldDynamicId);
        }
        public virtual void FastMoveTo(Vector3 v)
        {
            MoveTo(v);
        }

        public virtual int KillRadius
        {
            get { return 20; }
        }

        protected virtual bool SafeTP()
        {
            CharacterSettings.Instance.KillRadius = KillRadius;
            if (!Composites.IsUnitNear(15))
            {
                return true;
            }
            else
            {
                ProfileManager.CurrentProfile.KillMonsters = true;
                return false;
            }
        }
        public virtual void UseTP()
        {
            if (TPTimer.IsRunning && !IsCasting)
                TPTimer.Reset();
            if (TPTimer.IsRunning && TPTimer.ElapsedMilliseconds >= 5500)
            {
                Logger.Write("Casting TP took more than 5 seconds, retrying");
                var v = new Vector3(ZetaDia.Me.Position.X, ZetaDia.Me.Position.Y - 1, ZetaDia.Me.Position.Z);
                MoveTo(v);
                TPTimer.Reset();
            }
            if (!TPTimer.IsRunning)
            {
                TPTimer.Restart();
                // In world - not inside Sarkoth's dungeon
                if (ZetaDia.Me.WorldDynamicId == 1999503360)
                {
                    Composites.KillMonsters = false;
                    if (SafeTP())
                    {
                        ZetaDia.Me.UseTownPortal();
                    }
                }
                else
                {
                    ZetaDia.Me.UseTownPortal();
                }
            }
        }
        public virtual void PreCombat()
        {
            Composites.KillMonsters = true;
        }

        public static bool UsePowerSelf(SNOPower power)
        {
            return Composites.HasPower(power) && ZetaDia.Me.UsePower(power, Vector3.Zero, ZetaDia.Me.WorldDynamicId);
        }

        public static bool UsePowerAt(SNOPower power, Vector3 v)
        {
            return Composites.HasPower(power) && ZetaDia.Me.UsePower(power, v, ZetaDia.Me.WorldDynamicId);
        }

        public static bool UsePowerOn(SNOPower power, DiaUnit u)
        {
            return Composites.HasPower(power) && ZetaDia.Me.UsePower(power, u.Position, ZetaDia.Me.WorldDynamicId, u.ACDGuid);
        }

        public static bool IsCasting
        {
            get { return ZetaDia.Me.CommonData.AnimationState == AnimationState.Casting; }
        }
        public static ActorClass CharacterClass
        {
            get
            {
                if (ZetaDia.Me != null)
                {
                    return ZetaDia.Me.ActorClass;
                }
                else
                {
                    return ZetaDia.Service.CurrentHero.Class;
                }
            }
        }

        public virtual bool LootGold(IOrderedEnumerable<DiaItem> golds)
        {
            var gold = golds.FirstOrDefault();
            CheckToBlacklist(gold);
            if (gold != null)
            {
                var moveToPoint = Composites.VectorWithDistanceFrom(gold.Position, Composites.PickupRange);
                MoveTo(moveToPoint);
                return true;
            }
            return false;
        }
        public virtual bool LootItems(IOrderedEnumerable<DiaItem> items)
        {
            var loot = items.FirstOrDefault();
            CheckToBlacklist(loot);
            if (loot != null)
            {
                var moveToPoint = Composites.VectorWithDistanceFrom(loot.Position, 5);
                MoveTo(moveToPoint);
                PickupLoot(items);
                return true;
            }
            return false;
        }
        private void PickupLoot(IEnumerable<DiaItem> items)
        {
            foreach (var item in items)
            {
                if (item.Distance <= 10)
                    item.Interact();
            }
        }
        private void CheckToBlacklist(DiaItem item)
        {
            if (item == null)
                return;
            if (itemToLoot == null)
                itemToLoot = item;
            if (item == itemToLoot)
            {
                if (blacklistTimer.IsRunning && blacklistTimer.ElapsedMilliseconds >= 3000)
                {
                    blacklist.Add(item);
                    Logger.Write("{0} took longer than 3 seconds to loot, blacklisting", item.Name);
                }
                if (!blacklistTimer.IsRunning)
                {
                    blacklistTimer.Start();
                }
            }
            else
            {
                itemToLoot = item;
                blacklistTimer.Restart();
            }
        }
        public static void ClearBlacklist()
        {
            blacklist.Clear();
        }
    }
}
